﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;

namespace GabageFactory.Models
{
    public class EventReposity : Reposity
    {
        public List<EventRecordDetail> ListEventRecords(long factoryId, int status, Pagination pagination)
        {
            var events = from r in _dataContext.EventRecords
                         where (factoryId > 0 ? r.FactoryID == factoryId : true) && r.Status == status
                        orderby r.OccurredDate ascending, r.Id ascending
                            select r;

            List<EventRecord> erds = Pagination<EventRecord>(events, pagination);
            List<EventRecordDetail> result = new List<EventRecordDetail>();
            if (erds != null && erds.Count() > 0)
            {
                foreach (EventRecord e in erds)
                {
                    result.Add(GetEventDetail(e));
                }
            }

            return result;
        }

        public int GetEventCountByStatus(long factoryId, long recorderId, int status)
        {
            var events = from r in _dataContext.EventRecords
                         where (factoryId <= 0 || r.FactoryID == factoryId) && (recorderId <= 0 || r.RecorderId == recorderId) && r.Status == status
                         select r;

            return events == null ? 0 : events.Count();
        }

        public IEnumerable<EventRecordDetail> ListOnTrackEventRecords(long factoryId)
        {
            var events = from r in _dataContext.EventRecords
                         where (factoryId > 0 ? r.FactoryID == factoryId : true) && (r.Status == 0 || r.Status == 1)
                         orderby r.OccurredDate ascending, r.Id ascending
                         select r;
            foreach (EventRecord e in events)
            {
                yield return GetEventDetail(e);
            }
        }

        public IEnumerable<EventRecordDetail> SearchEventRecords(EventSearch es)
        {
            var events = from r in _dataContext.EventRecords
                         where (es.FactoryID > 0 ? r.FactoryID == es.FactoryID : true) && r.Status == 2
                         select r;
            

            
            if (es.Stack_Id > 0)
            {
                events = events.Where(item => (item.Stack_Id == es.Stack_Id && item.StackType == es.StackType));
            }

            if (es.Type > 0)
            {
                events = events.Where(item => (item.Type == es.Type));
            }

            if (es.Priority > 0)
            {
                events = events.Where(item => (item.Priority == es.Priority));
            }

            if (es.RecorderId > 0)
            {
                events = events.Where(item => (item.RecorderId == es.RecorderId));
            }

            if (es.dateType == 1)
            {
                int preDefinedDate = es.predefinedDate;
                if (preDefinedDate > 0)
                {
                    DateTime time = DateTime.Now.Date.AddDays(0 - preDefinedDate);
                    events = events.Where(item => item.OccurredDate.Date >= time);
                }
            }
            else if (es.dateType == 2)
            {
                DateTime dateFrom = es.dateFrom.Value;
                DateTime dateTo = es.dateTo.Value;
                events = events.Where(item => (item.OccurredDate.Date >= dateFrom && item.OccurredDate.Date <= dateTo));
            }

            DateTime time2 = DateTime.Now;
            switch (es.Days)
            {
                case 1:
                    time2 = DateTime.Now.Date.AddDays(-5);
                    events = events.Where(item => (item.OccurredDate.Date >= time2));
                    break;
                case 2:
                    time2 = DateTime.Now.Date.AddDays(-15);
                    events = events.Where(item => (item.OccurredDate.Date >= time2));
                    break;
                case 3:
                    time2 = DateTime.Now.Date.AddDays(-30);
                    events = events.Where(item => (item.OccurredDate.Date >= time2));
                    break;
                case 4:
                    time2 = DateTime.Now.Date.AddDays(-90);
                    events = events.Where(item => (item.OccurredDate.Date >= time2));
                    break;
                case 5:
                    time2 = DateTime.Now.Date.AddDays(-185);
                    events = events.Where(item => (item.OccurredDate.Date >= time2));
                    break;
                case 6:
                    time2 = DateTime.Now.Date.AddDays(-185);
                    events = events.Where(item => (item.OccurredDate.Date < time2));
                    break;
            }

            var ers = from r in events
                      orderby r.OccurredDate descending, r.Id descending
                      select r;

            List<EventRecord> result = new List<EventRecord>();
            if (ers != null)
            {
                es.TotalPage = (int)Math.Ceiling(ers.Count() * 1.0 / 15);
                es.PageNo = es.PageNo <= 0 ? 1 : (es.PageNo > es.TotalPage ? es.TotalPage : es.PageNo);
                es.TotalPage = es.TotalPage > 0 ? es.TotalPage : 1;

                int indexBegin = (es.PageNo - 1) * 15;
                int count = es.PageNo < es.TotalPage ? 15 : (ers.Count() - indexBegin);
                result = ers.ToList().GetRange(indexBegin, count);
            }

            foreach (EventRecord e in result)
            {
                yield return GetEventDetail(e);
            }
        }

        public EventRecord GetEventRecordById(long id)
        {
            var e = from r in _dataContext.EventRecords
                          where id == r.Id
                          select r;

            return e.First();
        }

        public EventRecord CreateEventRecord(EventRecord e)
        {
            _dataContext.EventRecords.InsertOnSubmit(e);
            SubmitChanges();
            return e;
        }

        public EventRecord UpdateEventRecord(EventRecord e)
        {
            SubmitChanges();
            return e;
        }

        public bool DeleteEventRecord(long eventId)
        {
            var events = from e in _dataContext.EventRecords
                         where e.Id == eventId
                         select e;

            if (events != null)
            {
                foreach (EventRecord e in events)
                {
                    _dataContext.EventRecords.DeleteOnSubmit(e);
                }
            }
            SubmitChanges();
            return true;
        }

        public bool DeleteEventDailyRecordByEventId(long eventId)
        {
            var events = from e in _dataContext.EventDailyRecords
                         where e.EventId == eventId
                         select e;

            if (events != null)
            {
                foreach (EventDailyRecord e in events)
                {
                    _dataContext.EventDailyRecords.DeleteOnSubmit(e);
                }
            }
            SubmitChanges();

            return true;
        }

        public IEnumerable<EventDailyRecord> ListEventDailyRecords(long id)
        {
            var events = from r in _dataContext.EventDailyRecords
                         where r.EventId == id
                         orderby r.OccurredDate ascending, r.Id ascending
                         select r;
            foreach (EventDailyRecord e in events)
            {
                yield return e;
            }
        }

        public EventDailyRecord GetEventDailyRecordById(long id)
        {
            var e = from r in _dataContext.EventDailyRecords
                    where id == r.Id
                    select r;

            return e.First();
        }

        public EventDailyRecord GetEventDailyRecordByEventId(long eventId)
        {
            var e = from r in _dataContext.EventDailyRecords
                    where eventId == r.EventId
                    orderby r.Id ascending
                    select r;

            return e.First();
        }

        public int GetCurrentProgress(long eventId)
        {
            var e = from r in _dataContext.EventDailyRecords
                    where eventId == r.EventId
                    orderby r.Progress descending
                    select r;

            if (e != null && e.Count() > 0)
            {
                return e.First().Progress;
            }
            else
            {
                return 0;
            }
        }

        public EventDailyRecord CreateEventDailyRecord(EventDailyRecord e)
        {
            _dataContext.EventDailyRecords.InsertOnSubmit(e);
            SubmitChanges();
            return e;
        }

        public EventDailyRecord UpdateEventDailyRecord(EventDailyRecord e)
        {
            SubmitChanges();
            return e;
        }

        public bool DeleteEventDailyRecord(EventDailyRecord e)
        {
            _dataContext.EventDailyRecords.DeleteOnSubmit(e);
            SubmitChanges();
            return true;
        }

        public EventRecordDetail GetEventDetail(EventRecord e)
        {
            if (e == null)
            {
                return null;
            }
            EventRecordDetail detail = new EventRecordDetail();
            detail.Id = e.Id;
            detail.CreateDate = e.CreateDate;
            detail.FactoryID = e.FactoryID;
            detail.Name = e.Name;
            detail.OccurredDate = e.OccurredDate;
            detail.Priority = e.Priority;
            detail.Progress = e.Progress;
            detail.RecorderId = e.RecorderId;
            detail.Stack_Id = e.Stack_Id;
            detail.StackType = e.StackType;
            detail.Status = e.Status;
            detail.Type = e.Type;
            detail.EndDate = e.EndDate ?? DateTime.Now;

            UserReposity userReposity = new UserReposity();
            User user = userReposity.GetUserById(e.RecorderId);
            if (user != null)
            {
                detail.UserName = user.RealName + "(" + user.Name + ")";
            }
            if (e.StackType == 0)
            {
                StackReposity stackReposity = new StackReposity();
                Stack stack = stackReposity.GetStackById(e.Stack_Id);
                detail.StackName = stack != null ? stack.Name : "";
            }
            else if (e.StackType == 1)
            {
                TailingpondReposity tailingpondReposity = new TailingpondReposity();
                Tailingpond tailingpond = tailingpondReposity.GetTailingpondById(e.Stack_Id);
                detail.StackName = tailingpond != null ? tailingpond.Name : "";
            }

            return detail;
        }
    }
}